// 注册表操作 RegCreateKey及Ex版本 RegCloseKey RegOpenKey及Ex RegDeleteKey RegSetValueKeyEx RegDeleteValue
#define selfroute1  L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"	//第一处自启动项
#define selfroute2  L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"	//第二处自启动项
#define RMAXLEN 150															//子路径最大长度（注册表）
struct add {
    HKEY root;
    LPCTSTR lpsubadd;
    PHKEY pkey;
    struct add* next;
};                                          //用于记录注册表键句柄及对应路径
struct add* head;
short from;
WCHAR route[RMAXLEN];

static LONG(WINAPI* OldRegCreateKey)(HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) = RegCreateKey;
static LONG(WINAPI* OldRegCreateKeyEx)(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) = RegCreateKeyEx;
static LONG(WINAPI* OldRegCloseKey)(HKEY hKey) = RegCloseKey;
static LONG(WINAPI* OldRegOpenKey)(HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) = RegOpenKey;
static LONG(WINAPI* OldRegOpenKeyEx)(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) = RegOpenKeyEx;
static LONG(WINAPI* OldRegDeleteKey)(HKEY hKey, LPCTSTR lpSubKey) = RegDeleteKey;
static LONG(WINAPI* OldRegSetValueEx)(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE* lpData, DWORD cbData) = RegSetValueEx;
static LONG(WINAPI* OldRegDeleteValue)(HKEY hKey, LPCTSTR lpValueName) = RegDeleteValue;
void key_route(HKEY hKey);  //追溯注册表句柄hKey对应路径

extern "C" __declspec(dllexport)LONG WINAPI NewRegCreateKey(HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegCreateKey HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

    printf("\nCreateKey：");
    struct add* temp;
    temp = (struct add*)malloc(sizeof(struct add));
    struct add* top = head;
    while (top->next != NULL)top = top->next;
    top->next = temp;
    temp->root = hKey;
    temp->lpsubadd = lpSubKey;
    temp->pkey = phkResult;
    temp->next = NULL;
    wcscpy_s(route, L"");
    key_route(*phkResult);

    std::cout << "，phkResult：" << phkResult;
    printf("\n********************************************\n\n");
    return OldRegCreateKey(hKey, lpSubKey, phkResult);
}

extern "C" __declspec(dllexport)LONG WINAPI NewRegCreateKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegCreateKeyEx HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);

    printf("\nCreateKey：");
    struct add* temp;
    temp = (struct add*)malloc(sizeof(struct add));
    struct add* top = head;
    while (top->next != NULL)top = top->next;
    top->next = temp;
    temp->root = hKey;
    temp->lpsubadd = lpSubKey;
    temp->pkey = phkResult;
    temp->next = NULL;
    wcscpy_s(route, L"");
    key_route(*phkResult);

    std::cout << "，phkResult：" << phkResult;
    printf("\n********************************************\n\n");
    return OldRegCreateKeyEx(hKey, lpSubKey, Reserved, lpClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
}

extern "C" __declspec(dllexport)LONG WINAPI NewRegCloseKey(HKEY hKey) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegCloseKey HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nCloseKey：");
    wcscpy_s(route, L"");
    key_route(hKey);
    printf("\n********************************************\n\n");
    return OldRegCloseKey(hKey);
}
extern "C" __declspec(dllexport)LONG WINAPI NewRegOpenKey(HKEY hKey, LPCTSTR lpSubKey, PHKEY phkResult) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegOpenKey HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nOpenKey：");
    struct add* temp;
    temp = (struct add*)malloc(sizeof(struct add));
    struct add* top = head;
    while (top->next != NULL)top = top->next;
    top->next = temp;
    temp->root = hKey;
    temp->lpsubadd = lpSubKey;
    temp->pkey = phkResult;
    temp->next = NULL;
    wcscpy_s(route, L"");
    key_route(*phkResult);

    std::cout << "，phkResult：" << phkResult;
    printf("\n********************************************\n\n");
    return OldRegOpenKey(hKey, lpSubKey, phkResult);
}

extern "C" __declspec(dllexport)LONG WINAPI NewRegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegOpenKeyEx HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nOpenKey：");
    struct add* temp;
    temp = (struct add*)malloc(sizeof(struct add));
    struct add* top = head;
    while (top->next != NULL)top = top->next;
    top->next = temp;
    temp->root = hKey;
    temp->lpsubadd = lpSubKey;
    temp->pkey = phkResult;
    temp->next = NULL;
    wcscpy_s(route, L"");
    key_route(*phkResult);

    std::cout << "，phkResult：" << phkResult;
    printf("\n********************************************\n\n");
    return OldRegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, phkResult);
}

extern "C" __declspec(dllexport)LONG WINAPI NewRegDeleteKey(HKEY hKey, LPCTSTR lpSubKey) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegDeleteKey HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nDeleteKey：");
    wcscpy_s(route, L"");
    key_route(hKey);
    printf("\\");
    wprintf(L"%s", lpSubKey);
    printf("\n********************************************\n\n");
    return OldRegDeleteKey(hKey, lpSubKey);
}
extern "C" __declspec(dllexport)LONG WINAPI NewRegSetValueEx(HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE * lpData, DWORD cbData) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegSetValueEx HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nKey：");

    wcscpy_s(route, L"");
    key_route(hKey);

    printf("，SetValueName：");
    wprintf(L"%s", lpValueName);
    printf("，Type：");
    if (dwType == REG_SZ)printf("字符串值");
    else if (dwType == REG_DWORD)printf("DWORD(32位)值");
    else if (dwType == REG_BINARY)printf("二进制值");
    printf("，Data：");
    wprintf(L"%s", lpData);
    if ((from == 1 && wcscmp(route, selfroute1) == 0) || from == 2 && wcscmp(route, selfroute2) == 0) {
        printf("\n程序试图添加自启动项");
    }
    printf("\n********************************************\n\n");
    return OldRegSetValueEx(hKey, lpValueName, Reserved, dwType, lpData, cbData);

}
extern "C" __declspec(dllexport)LONG WINAPI NewRegDeleteValue(HKEY hKey, LPCTSTR lpValueName) {
    GetLocalTime(&st);
    printf("\n\n*************************************************************\n");
    printf("RegSetValueEx HOOKED!\nDLL日志输出：%d-%d-%d %02d:%02d:%02d:%03d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
    printf("\nKey：");

    wcscpy_s(route, L"");
    key_route(hKey);

    printf("，DeleteValueName：");
    wprintf(L"%s", lpValueName);
    if ((from == 1 && wcscmp(route, selfroute1) == 0) || from == 2 && wcscmp(route, selfroute2) == 0) {
        printf("\n程序试图删除自启动项");
    }
    printf("\n********************************************\n\n");
    return OldRegDeleteValue(hKey, lpValueName);
}
void key_route(HKEY hKey) {
    struct add* top = head;
    top = top->next;
    while (*(top->pkey) != hKey && top->next != NULL)top = top->next;
    if (hKey == HKEY_CLASSES_ROOT ||
        hKey == HKEY_CURRENT_USER ||
        hKey == HKEY_LOCAL_MACHINE ||
        hKey == HKEY_USERS ||
        hKey == HKEY_CURRENT_CONFIG
        ) {
        if (hKey == HKEY_CLASSES_ROOT) { printf("HKEY_CLASSES_ROOT:"); from = 0; }
        else if (hKey == HKEY_CURRENT_USER) { printf("HKEY_CURRENT_USER:"); from = 1; }
        else if (hKey == HKEY_LOCAL_MACHINE) { printf("HKEY_LOCAL_MACHINE:"); from = 2; }
        else if (hKey == HKEY_USERS) { printf("HKEY_USERS:"); from = 3; }
        else if (hKey == HKEY_CURRENT_CONFIG) { printf("HKEY_CURRENT_CONFIG:"); from = 4; }
        return;
    }
    if (top->root == HKEY_CLASSES_ROOT) { printf("HKEY_CLASSES_ROOT:\\"); from = 0; }
    else if (top->root == HKEY_CURRENT_USER) { printf("HKEY_CURRENT_USER:\\"); from = 1; }
    else if (top->root == HKEY_LOCAL_MACHINE) { printf("HKEY_LOCAL_MACHINE:\\"); from = 2; }
    else if (top->root == HKEY_USERS) { printf("HKEY_USERS:\\"); from = 3; }
    else if (top->root == HKEY_CURRENT_CONFIG) { printf("HKEY_CURRENT_CONFIG:\\"); from = 4; }
    else {
        key_route(top->root);
        wcscat_s(route, L"\\");
        wprintf(L"\\");
    }
    wcscat_s(route, top->lpsubadd);
    wprintf(L"%s", top->lpsubadd);
}
// 注册表部分